﻿using System;
using System.Linq;
using System.Windows.Forms;
using System.IO;

namespace MyComputer
{
    public partial class MyComputerForm : Form
    {
        public MyComputerForm()
        {
            InitializeComponent();
        }

        string[] drives = Environment.GetLogicalDrives();
        private string currentDirectory = "Computer";

        private void MyComputerForm_Load(object sender, EventArgs e)
        {
            
            //Directories TreeView
            foreach (string drive in drives)
            {
                directoriesTreeView.Nodes.Add(drive);
            }
            foreach (TreeNode partition in directoriesTreeView.Nodes)
            {
                populateDirectories(partition.Text, partition);
            }

            //Directories ListView
            directionTextBox.Text = currentDirectory;
            foreach (string drive in drives)
            {
                ListViewItem newDrive = directoriesListView.Items.Add(drive);
                newDrive.ImageIndex = 2;
            }

        }

        #region Directories TreeView

        private void populateDirectories(string currentDirectory, TreeNode parentNode)
        {
            try
            {
                string[] subdirectories = Directory.GetDirectories(currentDirectory);

                if (subdirectories.Length != 0)
                {
                    foreach (var subdirectory in subdirectories)
                    {
                        string directoryName = Path.GetFileName(subdirectory);
                        TreeNode newNode = new TreeNode(directoryName);
                        parentNode.Nodes.Add(newNode);

                        try
                        {
                            if (Directory.EnumerateDirectories(subdirectory).Any())
                                newNode.Nodes.Add("Fictive node");
                        }
                        catch (UnauthorizedAccessException)
                        {
                            newNode.Nodes.Add("Access denided");
                        }
                    }
                }
            }
            catch (IOException)
            {
                //IOException
            }
            catch (UnauthorizedAccessException)
            {
                parentNode.Nodes.Add("Access denided");
            }
        }

        private void directoriesTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            string directory = e.Node.FullPath;

            if (e.Node.Parent != null)
                directory = directory.Remove(2, 1);

            e.Node.Nodes.Clear();
            populateDirectories(directory, e.Node);
        }

        private void collapseAllButton_Click(object sender, EventArgs e)
        {
            directoriesTreeView.CollapseAll();
        }

        private void directoriesTreeView_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
        {
            e.Node.Nodes.Clear();
            e.Node.Nodes.Add("Fictive node");
        }

        #endregion Directories TreeView

        #region Directories ListView

        private void directoriesListView_DoubleClick(object sender, EventArgs e)
        {
            if (directoriesListView.SelectedItems.Count != 0)
            {
                if (directoriesListView.Items[0].Selected && currentDirectory != "Computer")
                {
                    DirectoryInfo previousDirectory = new DirectoryInfo(currentDirectory);

                    if (previousDirectory.Parent != null)
                    {
                        LoadFilesInDirectory(previousDirectory.Parent.FullName);
                    }
                    else
                    {
                        currentDirectory = "Computer";
                        LoadComputer();
                    }
                }
                else
                {
                    string chosen = directoriesListView.SelectedItems[0].Text;
                    string selectedItem = currentDirectory == 
                        "Computer" ? chosen : currentDirectory + "\\" + chosen;
                    bool isFile = new FileInfo(selectedItem).Exists;

                    if (isFile)
                    {
                        try
                        {
                            System.Diagnostics.Process.Start(selectedItem);
                        }
                        catch (SystemException)
                        {
                            MessageBox.Show("System can't open this file", "Open file error", 
                                    MessageBoxButtons.OKCancel, 
                                    MessageBoxIcon.Error);
                        }
                        
                    }
                    else
                    {
                        try
                        {
                            if (currentDirectory != "Computer")
                            {
                                if (Directory.Exists(Path.Combine(currentDirectory, chosen)))
                                {
                                    LoadFilesInDirectory(Path.Combine(currentDirectory, chosen));
                                }
                            }
                            else
                            {
                                try
                                {
                                    LoadFilesInDirectory(chosen);
                                }
                                catch (IOException)
                                {
                                    MessageBox.Show("Warring: this device is not ready", "Attention",
                                            MessageBoxButtons.OK,
                                            MessageBoxIcon.Warning);
                                }
                            }
                        }
                        catch (NotSupportedException)
                        {
                            MessageBox.Show("Warring: this device or directory is not supported by this operating system", "Attention",
                                        MessageBoxButtons.OK,
                                        MessageBoxIcon.Warning);
                        }
                    }
                }
            }
            directionTextBox.Text = currentDirectory;
        }

        private void LoadFilesInDirectory(string currentDirectoryName)
        {
            try
            {
                directoriesListView.Items.Clear();
                directoriesListView.Items.Add("<--Back");
                currentDirectory = currentDirectoryName;
                DirectoryInfo newCurrentDirectory = new DirectoryInfo(currentDirectory);

                DirectoryInfo[] directoryArray = newCurrentDirectory.GetDirectories();
                FileInfo[] fileArray = newCurrentDirectory.GetFiles();

                foreach (DirectoryInfo directoryInfo in directoryArray)
                {
                    ListViewItem newDirectoryItem = directoriesListView.Items.Add(directoryInfo.Name);
                    newDirectoryItem.ImageIndex = 1;
                }

                foreach (FileInfo fileInfo in fileArray)
                {
                    ListViewItem newFileItem = directoriesListView.Items.Add(fileInfo.Name);
                    newFileItem.ImageIndex = 0;
                }
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("Warring: Some files may note be visible due to permission settings",
                                "Attention", 0, MessageBoxIcon.Warning);
            }
        }

        private void directionTextBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            string previouesDirectoryValue = currentDirectory;

            if (e.KeyChar == (char) Keys.Enter)
            {
                if (Directory.Exists(directionTextBox.Text))
                {
                    LoadFilesInDirectory(directionTextBox.Text);
                }
                else
                {
                    if (directionTextBox.Text.IndexOf("computer", StringComparison.CurrentCultureIgnoreCase) >= 0)
                    {
                        currentDirectory = directionTextBox.Text = "Computer";
                        LoadComputer();
                    }
                    else
                    {
                        directionTextBox.Text = previouesDirectoryValue;
                        directionTextBox.Select(directionTextBox.Text.Length, 0);    
                    }                    
                }
                e.Handled = true;
            }          
        }

        private void LoadComputer()
        {
            directoriesListView.Items.Clear();            

            foreach (string drive in drives)
            {
                ListViewItem newDrive = directoriesListView.Items.Add(drive);
                newDrive.ImageIndex = 2;
            }
        }       

        private void homeButton_Click(object sender, EventArgs e)
        {
            currentDirectory = directionTextBox.Text = "Computer";
            LoadComputer();
        }

        #endregion Directories ListView
    }
}
